/*
Copyright (C) 2014  Johan Degraeve

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/gpl.txt>.

*/

package helpdiabetesj2me;

import javax.microedition.lcdui.*;
import javax.microedition.lcdui.Font;
import javax.microedition.rms.*;

/**
 *
 * @author Johan
 */
public class DeepSearch extends MyCanvas implements CommandListener, Runnable {
     static final String[] str_terug = {"Terug"};
     static final String[] str_kiezen = {"Kiezen"};
     static final String[] str_searching = {"..Zoeken bezig.."};
     static final String[] str_no_items_found_yet = {"Nog geen items gevonden"};
     static final String[] str_no_items_found = {"Zoeken afgewerkt. Geen items gevonden"};
     static final String[] str_items_found = {"Items gevonden :"};
     
    
    // maximum number of items that will be searched. Searching will stop when max_items are found
    static final int max_items = 50;
    // array of record id's containg items that contain the search string
    int[] itemsfoundar;
    //nr of items found so far
    int itemsfound;
    
    //used in search algorithm
    // made global because value is used in paint() to determine size of status bar
    int cnt1;

    private Command Kiezen;
    private Command Terug;
    
    boolean proceed;//indicates to search if it needs to proceed or not
    

    //points to the record in itemsfoundar that is first shown
    // shownrecid = 1 means first record ie itemsfoundar[0]
    private int shownrecid;
    
    public DeepSearch(Font userfont, HelpDiabetes midlet) {
         super(userfont,midlet);
         // don't need this field'
         enteredstring = null;
         shownrecid = 1;
         itemsfoundar = new int[max_items];
         
         resetexittimer();
         
         Terug = new Command(str_terug[HelpDiabetes.languageIndex],str_terug[HelpDiabetes.languageIndex],Command.EXIT,1);
         this.addCommand(Terug);
         Kiezen = new Command(str_kiezen[HelpDiabetes.languageIndex],str_kiezen[HelpDiabetes.languageIndex],Command.OK,2);
         this.setCommandListener(this);
         
    }

    void search() {
        itemsfound=0;
        shownrecid = 1;
        proceed = true;
        curdisp = midlet.getDisplay().getCurrent();
        if (HelpDiabetes.getitemfromuser.enteredstring.enteredstringlength > 0) { // if there's nothing in the enteredstring then do nothing'
            midlet.getDisplay().setCurrent(this);
            //setscrsize();
            new Thread(this).start();
            repaint();
        }
    }
    
    /* start searching for items that contain the searchstring */
    public void run() {
        int cnt2,cnt3;
        boolean found;
        int localblength = 0;
        byte[] localb =  new byte[MyCanvas.maxblength] ;
            
                repaint();    

                for (cnt1 = FoodFile.nrofrecstoskip + 1;cnt1 < GetItemFromUser.foodrssize + 1;cnt1++) {
                    if (itemsfound == max_items) break;// if maximum reached, stop searching
                    found = false;
                    if (!proceed) break;// stop searching
                    try {
                        localblength = FoodFile.getRecord(cnt1,localb,0);
                        for (cnt2 = 0;cnt2 < localblength;cnt2++) {
                            if (localb[cnt2] == ',')
                                break;//jump out of the for loop since ',' is encountered'
                            else {
                                for (cnt3 = 0;cnt3 < HelpDiabetes.getitemfromuser.enteredstring.enteredstringlength;cnt3++) {
                                    if ((int)charorder[0xFF & localb[cnt2+cnt3]] != (int)charorder[HelpDiabetes.getitemfromuser.enteredstring.enteredstring[cnt3]]) {
                                        break;//found a different character
                                    }
                                    else if (cnt3 == (HelpDiabetes.getitemfromuser.enteredstring.enteredstringlength) - 1) {
                                        found = true;;//we've compared all characters in the searchstring'
                                        itemsfoundar[itemsfound] = cnt1;
                                        itemsfound++;
                                        repaint();
                                    }
                                    if (found)
                                        break;
                                }
                                if (found) 
                                    break;
                            }
                        }
                    } catch (RecordStoreNotOpenException ex) {
                        (new ReportException()).Report("RecordStoreNotOpenException in DeepSearch.run()",ex,false);        
                    } catch (InvalidRecordIDException ex) {
                        (new ReportException()).Report("InvalidRecordIDException in DeepSearch.run()",ex,false);        
                    } catch (RecordStoreException ex) {
                        (new ReportException()).Report("RecordStoreException in DeepSearch.run()",ex,false);        
                    } catch (ArrayIndexOutOfBoundsException ex) {
                        (new ReportException()).Report("ArrayIndexOutofboundsException in DeepSearch.run()."
                                ,ex,false);
                    }

                }
                proceed = false;
                repaint();
        
    }
    
    protected void paint(Graphics graphics) {
        int tempid;
        x=0;y=0;
        // here the full screen will be drawn

        //first set the font to the one passed to the constructor of DeepSearch
        graphics.setFont(userfont);

        //clear the screen 
        graphics.setColor(255,255,255);
        graphics.fillRect(0, 0, scrwidth, scrhght);
        
        //display  ...searching.. in a status bar
        if (proceed) {
            // first print '..searching..' non inverted
            // then set clipregion to a width corresponding to the number of items search and reprint inverted, filling to the rest of the screen
            paintstring(str_searching[HelpDiabetes.languageIndex].getBytes(),false,graphics,userfont);
            x=0;
            graphics.setClip(0,0,(scrwidth*cnt1)/GetItemFromUser.foodrssize,scrhght);
            paintstring(str_searching[HelpDiabetes.languageIndex].getBytes(),true,graphics,userfont);
            //this is to make the line inverted for the whole width of the screen
            graphics.setColor(0,0,0);
            graphics.fillRect(x,y,scrwidth-x,fonthght);
            graphics.setColor(255,255,255);
            graphics.setClip(0,0,scrwidth,scrhght);
            x=0;y=y+fonthght;
        }
        
        try {
        
           if (itemsfound > 0) {
               this.addCommand(Kiezen); 
               paintstring(str_items_found[HelpDiabetes.languageIndex].getBytes(),false,graphics,userfont);
               x=0;y=y+fonthght;
               blength = FoodFile.getRecord(itemsfoundar[shownrecid-1],b,0);
               //first record to be shown inverted
               paintstring(b,blength,true,graphics,userfont);
               //this is to make the line inverted for the whole width of the screen
               graphics.setColor(0,0,0);
               graphics.fillRect(x,y,scrwidth-x,fonthght);
               graphics.setColor(255,255,255);
               x=0;y=y+fonthght;
               // now draw next elements normal, if there are any, and as long as screensize not exceeded
               tempid = shownrecid + 1;
               while (tempid < itemsfound + 1 & (y < scrhght)) {
                   blength = FoodFile.getRecord(itemsfoundar[tempid-1],b,0);
                   paintstring(b,blength,false,graphics,userfont);
                   x=0;y=y+fonthght;
                   tempid++;
               }
           } else {
                this.removeCommand(Kiezen);
                if (proceed) 
                      paintstring(str_no_items_found_yet[HelpDiabetes.languageIndex].getBytes(),false,graphics,userfont);
                else
                      paintstring(str_no_items_found[HelpDiabetes.languageIndex].getBytes(),false,graphics,userfont);
           }

       } catch (RecordStoreNotOpenException ex1) {
            (new ReportException()).Report("RecordStoreNotOpenException in DeepSearch.paint",ex1,false);
       } catch (RecordStoreNotFoundException ex3) {
            (new ReportException()).Report("RecordStoreNotFoundException in DeepSearch.paint",ex3,false);
       } catch (Exception ex2) {
            (new ReportException()).Report("Exception in DeepSearch.paint",ex2,false);
       }
    }

    public void commandAction(Command command, Displayable displayable) {
        resetexittimer();
        if (command == Kiezen) {
            keyPressed(getKeyCode(FIRE));
        } else if (command == Terug) {
            midlet.getDisplay().setCurrent(curdisp);
        }
    }
    
    //will be used to check if user presses up or down key, in order to scroll through the list
    public synchronized void keyPressed (int keyCode) {
            resetexittimer();
       switch(getGameAction(keyCode)) {
            case UP:
                    if (shownrecid > 1) {
                        shownrecid--;
                        repaint();
                    }
                    break;
            case DOWN:
                    if (shownrecid < itemsfound) {
                         shownrecid++;
                          repaint();
                    }
                    break;
            case FIRE:
                    if (itemsfound > 0) {
                        proceed = false;
                        
                        //call additem
                        HelpDiabetes.getitemfromuser.additem.ItemSelected(itemsfoundar[shownrecid-1],true,"0.0",0,1);
                    }
                    
                    break;
               default:;
            } // end switch statement
    }

    String GetClassName() {
        return("DeepSearch");
    }

    //overloading necessary to allow checking if user hits the first highlighted line
    protected void pointerPressed(int x, int y) {
        //boundaries in which x and y should fall to say that first line is hit
        int y_start;
        int y_end;

        y_start = fonthght; //Items found:
        if (proceed) {
           y_start = y_start + fonthght; //Items found :
        }

        y_end = y_start + fonthght;

        if ((y_start - 1) < y && y < y_end) {
            keyPressed(Key_code_FIRE);
        } else {
            super.pointerPressed(x, y);
        }
    }

}
